//
// File.cpp
//
// $Id: //poco/1.4/Foundation/src/File.cpp#3 $
//
// Library: Foundation
// Package: Filesystem
// Module:  File
//
// Copyright (c) 2004-2006, Applied Informatics Software Engineering GmbH.
// and Contributors.
//
// SPDX-License-Identifier:	BSL-1.0
//


#include "Poco/File.h"
#include "Poco/Path.h"
#include "Poco/DirectoryIterator.h"
#include <iostream>

#if defined(POCO_OS_FAMILY_UNIX)
#include "File_UNIX.cpp"
#endif


namespace Poco {


File::File()
{
}


File::File(const std::string& path): m_path(path)
{
    init();
}


File::File(const char* path): m_path(path)
{
    init();
}


File::File(const Path& path):m_path(path.toString())
{
    init();
}


File::~File()
{
}

File::File(const File& file)
{
	m_path = file.m_path;
    init();
}

File& File::operator = (const std::string& path)
{
	m_path = path;
	init();
	return *this;
}

File& File::operator = (const Path& path)
{
	m_path = path.toString();
    init();
    return *this;
}

File& File::operator = (const File& file)
{
	m_path = file.m_path;
	init();
	
	return *this;
}


File& File::operator = (const char* path)
{
	poco_check_ptr (path);
	m_path = std::string(path);
	init();
	return *this;
}

void File::init()
{
    std::string::size_type n = m_path.size();
    if (n > 1 && m_path[n - 1] == '/')
        m_path.resize(n - 1);
}

void File::copyTo(const std::string& path) const
{
	Path src(m_path);
	Path dest(path);
	File destFile(path);
	if ((destFile.exists() && destFile.isDirectory()) || dest.isDirectory())
	{
		dest.makeDirectory();
		dest.setFileName(src.getFileName());
	}
	if (isDirectory())
		copyDirectory(dest.toString());
	else
		copyToFile(dest.toString());
}


void File::copyDirectory(const std::string& path) const
{
	File target(path);
	target.createDirectories();

	Path src(m_path);
	src.makeFile();
	DirectoryIterator it(src);
	DirectoryIterator end;
	for (; it != end; ++it)
	{
		it->copyTo(path);
	}
}


void File::moveTo(const std::string& path)
{
	copyTo(path);
	remove(true);
    
	m_path      = path;
}

bool File::createFile()
{
    int n = open(m_path.c_str(), O_WRONLY | O_CREAT | O_EXCL, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP | S_IROTH | S_IWOTH);
    if (n != -1)
    {
        close(n);
        return true;
    }
    if (n == -1 && errno == EEXIST)
        return false;
    else
        handleLastError(m_path);
    return false;
}

void File::createDirectories()
{
	if (!exists())
	{
		Path p(m_path);
		p.makeDirectory();
		if (p.depth() > 1)
		{
			p.makeParent();
			File f(p);
			f.createDirectories();
		}
		createDirectory();
	}
}


void File::list(std::vector<std::string>& files) const
{
    files.clear();
    DirectoryIterator it(*this);
    DirectoryIterator end;
    while (it != end)
    {
        files.push_back(it.name());
        ++it;
    }
}


void File::list(std::vector<File>& files) const
{
    files.clear();
    DirectoryIterator it(*this);
    DirectoryIterator end;
    while (it != end)
    {
        files.push_back(*it);
        ++it;
    }
}

} // namespace Poco
